#pragma once

#include <memory>
#include <cstdint>
#include <boost/noncopyable.hpp>
#include <DB/Core/Types.h>


namespace DB
{

class Block;
class IColumn;
class IDataType;
struct Progress;


/** Interface of stream for writing data by rows (for example: for output to terminal).
  */
class IRowOutputStream : private boost::noncopyable
{
public:

	/** Write a row.
	  * Default implementation calls methods to write single values and delimiters
	  * (except delimiter between rows (writeRowBetweenDelimiter())).
	  */
	virtual void write(const Block & block, size_t row_num);

	/** Write single value. */
	virtual void writeField(const IColumn & column, const IDataType & type, size_t row_num) = 0;

	/** Write delimiter. */
	virtual void writeFieldDelimiter() {};		/// delimiter between values
	virtual void writeRowStartDelimiter() {};	/// delimiter before each row
	virtual void writeRowEndDelimiter() {};		/// delimiter after each row
	virtual void writeRowBetweenDelimiter() {};	/// delimiter between rows
	virtual void writePrefix() {};				/// delimiter before resultset
	virtual void writeSuffix() {};				/// delimiter after resultset

	/** Flush output buffers if any. */
	virtual void flush() {}

	/** Methods to set additional information for output in formats, that support it.
	  */
	virtual void setRowsBeforeLimit(size_t rows_before_limit) {}
	virtual void setTotals(const Block & totals) {}
	virtual void setExtremes(const Block & extremes) {}

	/** Notify about progress. Method could be called from different threads.
	  * Passed value are delta, that must be summarized.
	  */
	virtual void onProgress(const Progress & progress) {}

	/** Content-Type to set when sending HTTP response. */
	virtual String getContentType() const { return "text/plain; charset=UTF-8"; }

	virtual ~IRowOutputStream() {}
};

using RowOutputStreamPtr = std::shared_ptr<IRowOutputStream>;

}
